//已知存在一个按非降序排列的整数数组 nums ，数组中的值不必互不相同。 
//
// 在传递给函数之前，nums 在预先未知的某个下标 k（0 <= k < nums.length）上进行了 旋转 ，使数组变为 [nums[k], nums
//[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]（下标 从 0 开始 计数）。例如， [0,1,
//2,4,4,4,5,6,6,7] 在下标 5 处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4] 。 
//
// 给你 旋转后 的数组 nums 和一个整数 target ，请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 targ
//et ，则返回 true ，否则返回 false 。 
//
// 
//
// 示例 1： 
//
// 
//输入：nums = [2,5,6,0,0,1,2], target = 0
//输出：true
// 
//
// 示例 2： 
//
// 
//输入：nums = [2,5,6,0,0,1,2], target = 3
//输出：false 
//
// 
//
// 提示： 
//
// 
// 1 <= nums.length <= 5000 
// -104 <= nums[i] <= 104 
// 题目数据保证 nums 在预先未知的某个下标上进行了旋转 
// -104 <= target <= 104 
// 
//
// 
//
// 进阶： 
//
// 
// 这是 搜索旋转排序数组 的延伸题目，本题中的 nums 可能包含重复元素。 
// 这会影响到程序的时间复杂度吗？会有怎样的影响，为什么？ 
// 
// Related Topics 数组 二分查找 
// 👍 446 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public boolean search(int[] nums, int target) {
        //判断两端是否跟target相等
        if(nums[0] == target || nums[nums.length-1] == target) return true;
        //注意定义好边界
        int left = 0, right = nums.length - 1;
        //将左边的重复元素跳过，注意边界条件是 head+1
        while(left+1 < nums.length && nums[left] == nums[left+1]){
            left ++;
        }
        //将右边跟左边相等的元素跳过
        while(right > 0 && nums[right] == nums[left]){
            right --;
        }

        int head = left, tail = right, mid;
        //此时，左右两个半段，就不会有元素重叠了，注意是<=
        while(head <= tail){
            mid = head + ((tail - head)>>1);
            System.out.println("A\thead:"+head+",tail:"+tail+",mid:"+mid);
            if(nums[mid] == target){
                return true;
            }
            System.out.println("...target:"+target+",nums[mid]:"+nums[mid]+",mid:"+mid);
            //先判断mid是在哪个半段，注意有”=“号，注意是与left比较
            //如果mid是在左半段
            if(nums[mid] >= nums[left]){
                //target在左半段
                if(target > nums[mid]){
                    head = mid + 1;
                }
                //target不一定在左半段
                else {
                    //target 在 左半段
                    if(target > nums[right]){
                        tail = mid -1;
                    }
                    //target 在 右半段
                    else{
                        head = mid + 1;
                    }
                }

            }else{
                //否则mid在右半段
                //target在右半段
                if(target < nums[mid]){
                    tail = mid - 1;
                }
                //target不一定在右半段
                else{
                    //target 在 左半段
                    if(target > nums[right]){
                        tail = mid - 1;
                    }
                    //target 在 右半段
                    else{
                        head = mid + 1;
                    }
                }
            }
            System.out.println("B\thead:"+head+",tail:"+tail+",mid:"+mid);
        }
        return false;
    }
}
//leetcode submit region end(Prohibit modification and deletion)